package mongo;

import com.mongodb.BasicDBObject;
import com.mongodb.DBObject;
import com.mongodb.client.FindIterable;
import com.mongodb.client.MongoCursor;
import com.mongodb.client.model.Filters;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.List;

import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.bson.Document;
import org.bson.types.ObjectId;

import com.mongodb.MongoClient;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoDatabase;

public class UserAccount {
    MongoCollection<Document> UserAccount;
    
    public UserAccount(){
        try{
        	MongoDatabase mongoDatabase = mongoConnet.getMongoDatabase();
            UserAccount = mongoDatabase.getCollection("UserAccount");
        }catch(Exception e){
            System.err.println( e.getClass().getName() + ": " + e.getMessage() );
        }
    }
    
    
    public Document verifyLogin(String username,String password){
        try{
            BasicDBObject queryObject = new BasicDBObject("username",username).append("password", password);
            FindIterable<Document> findIterable = UserAccount.find(queryObject);
            MongoCursor<Document> mongoCursor = findIterable.iterator();
            if(mongoCursor.hasNext()){
            	Document result = mongoCursor.next();
            	result.append("login", true);
            	return result;
            }else{
            	return new Document("login",false);
            } 
        }catch(Exception e){
            System.err.println( e.getClass().getName() + ": " + e.getMessage() );
            return new Document("login",false);
        }
    }
    
    public Boolean isExistUser(String username){
        try{
            BasicDBObject queryObject = new BasicDBObject("username",username);
            FindIterable<Document> findIterable = UserAccount.find(queryObject);
            MongoCursor<Document> mongoCursor = findIterable.iterator();
            if(mongoCursor.hasNext()){
            	return true;
            }else{
            	return false;
            } 
        }catch(Exception e){
            System.err.println( e.getClass().getName() + ": " + e.getMessage() );
            return true;
        }
    }
    
    public Boolean isRegisterSuccess(String username,String password,String type){
        try{
        	UserAccount.insertOne(new Document("username",username).append("password", password).append("type", type).append("sex", "男").append("isopen", true));
        	return true;
        }catch(Exception e){
            System.err.println( e.getClass().getName() + ": " + e.getMessage() );
            return false;
        }
    }
    
    public boolean update(ObjectId id,Document document){
        try{
        	UserAccount.updateOne(Filters.eq("_id", id), new Document("$set",document));
            return true;
        }catch(Exception e){
            System.err.println( e.getClass().getName() + ": " + e.getMessage() );
            return false;
        }
    }
    
    public MongoCursor<Document> query(BasicDBObject queryObject){
        try{
            FindIterable<Document> findIterable = UserAccount.find(queryObject);
            MongoCursor<Document> mongoCursor = findIterable.iterator();
            return mongoCursor;
        }catch(Exception e){
            System.err.println( e.getClass().getName() + ": " + e.getMessage() );
            return null;
        }
    }
    
    public Boolean delete(ObjectId _id){
        try{
            BasicDBObject queryObject = new BasicDBObject("_id",_id);
            UserAccount.deleteOne(queryObject);
            return true;
        }catch(Exception e){
            System.err.println( e.getClass().getName() + ": " + e.getMessage() );
            return false;
        }
    }
    
    
    public Boolean add(Document newUser){
    	try{
    		UserAccount.insertOne(newUser.append("password", "123456").append("isopen", true));
    		return true;
    	}catch(Exception e){
            System.err.println( e.getClass().getName() + ": " + e.getMessage() );
            return false;
    	}
    }
    
    public List<String> batchAdd(String fileDir,String type){
    	try{
    		List<String> result = new ArrayList<String>();
    		List<Document> userList =  new ArrayList<Document>();
    		String prefix=fileDir.substring(fileDir.lastIndexOf(".")+1);
    		System.out.println(prefix);
    		if(prefix.equals("xls")){
    			userList = this.readByXls(fileDir);
    		}else if(prefix.equals("xlsx")){
    			userList = this.readByXlsx(fileDir);
    		}else{
    			return null;
    		}
    		for(int i=0;i<userList.size();i++){
    			userList.get(i).append("password", "123456").append("isopen", true).append("type", type);
    			if(this.isExistUser(userList.get(i).getString("username"))){
    				result.add(userList.get(i).getString("username"));
    			}else{
    				this.add(userList.get(i));
    			}
    		}
    		System.out.println("batchAddSuccess");
    		return result;
    	}catch(Exception e){
            System.err.println( e.getClass().getName() + ": " + e.getMessage() );
            return null;
    	}
    }
    
    @SuppressWarnings("deprecation")
	private List<Document> readByXls(String fileDir) throws IOException{
    	List<Document> result = new ArrayList<Document>();
    	try {    		
			InputStream is = new FileInputStream(fileDir);
			HSSFWorkbook hssfworkbook = new HSSFWorkbook(is);
			for(int numSheet = 0 ; numSheet < hssfworkbook.getNumberOfSheets();numSheet++){
				HSSFSheet hssfSheet = hssfworkbook.getSheetAt(numSheet);
				if(hssfSheet == null){
					continue;
				}

				HSSFRow firstRow = hssfSheet.getRow(0);
				int allElements = firstRow.getLastCellNum();
				for(int rowNum = 1; rowNum <= hssfSheet.getLastRowNum();rowNum++){
					HSSFRow hssfRow = hssfSheet.getRow(rowNum);
					Document user = new Document();
					for(int i=0;i<allElements;i++){
						if(hssfRow.getCell(i) !=null){
							String cellValue = "";
		                    switch (hssfRow.getCell(i).getCellType()) {  
		                    case HSSFCell.CELL_TYPE_NUMERIC: // 数字  
		                        DecimalFormat df = new DecimalFormat("0");  
		                        cellValue = df.format(hssfRow.getCell(i).getNumericCellValue());  
		                        break;  
		  
		                    case HSSFCell.CELL_TYPE_STRING: // 字符串  
		                        cellValue = hssfRow.getCell(i).getStringCellValue();  
		                        break;  
		                        
		                    case HSSFCell.CELL_TYPE_FORMULA: // 公式  
		                        cellValue = hssfRow.getCell(i).getCellFormula() + "";  
		                        break;  
		                        
		                    case HSSFCell.CELL_TYPE_ERROR: // 故障  
		                        cellValue = "非法字符";  
		                        break;  
		  
		                    default:  
		                        cellValue = "未知类型";  
		                        break;  
		                    }  
							user.append(firstRow.getCell(i).toString(), cellValue);
						}else{
							user.append(firstRow.getCell(i).toString(), "无");
						}
					}
					result.add(user);
					}
				
			}
			return result;
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
    	return result;
    }
	
    
    private List<Document> readByXlsx(String fileDir) throws IOException{
    	List<Document> result = new ArrayList<Document>();
    	try {    		
			InputStream is = new FileInputStream(fileDir);
			XSSFWorkbook xssfworkbook = new XSSFWorkbook(is);
			for(int numSheet = 0 ; numSheet < xssfworkbook.getNumberOfSheets();numSheet++){
				XSSFSheet xssfSheet = xssfworkbook.getSheetAt(numSheet);
				if(xssfSheet == null){
					continue;
				}

				XSSFRow firstRow = xssfSheet.getRow(0);
				int allElements = firstRow.getLastCellNum();
				for(int rowNum = 1; rowNum <= xssfSheet.getLastRowNum();rowNum++){
					XSSFRow hssfRow = xssfSheet.getRow(rowNum);
					Document user = new Document();
					for(int i=0;i<allElements;i++){
						if(hssfRow.getCell(i) !=null){
							String cellValue = "";
		                    switch (hssfRow.getCell(i).getCellType()) {  
		                    case HSSFCell.CELL_TYPE_NUMERIC: // 数字  
		                        DecimalFormat df = new DecimalFormat("0");  
		                        cellValue = df.format(hssfRow.getCell(i).getNumericCellValue());  
		                        break;  
		  
		                    case HSSFCell.CELL_TYPE_STRING: // 字符串  
		                        cellValue = hssfRow.getCell(i).getStringCellValue();  
		                        break;  
		                        
		                    case HSSFCell.CELL_TYPE_FORMULA: // 公式  
		                        cellValue = hssfRow.getCell(i).getCellFormula() + "";  
		                        break;  
		  
		                    case HSSFCell.CELL_TYPE_ERROR: // 故障  
		                        cellValue = "非法字符";  
		                        break;  
		  
		                    default:  
		                        cellValue = "未知类型";  
		                        break;  
		                    }  
							user.append(firstRow.getCell(i).toString(), cellValue);
						}else{
							user.append(firstRow.getCell(i).toString(), "无");
						}
					}
					result.add(user);
					}
				
			}
			return result;
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
	    	return result;
		}
    }
    
    public Boolean changePwd(ObjectId _id,String newPwd){
    	try{	
    		UserAccount.updateOne(Filters.eq(_id), new Document("$set",new Document("password",newPwd)));
    		return true;
    	}catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return false;
		}
    }
    
    public Boolean changeOpen(ObjectId _id,Boolean newOpenState){
    	try{	
    		UserAccount.updateOne(Filters.eq(_id), new Document("$set",new Document("isopen",newOpenState)));
    		return true;
    	}catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return false;
		}
    }
    
    public Document getUserInfo(Object _id){
        try{
            BasicDBObject queryObject = new BasicDBObject("_id",_id);
            FindIterable<Document> findIterable = UserAccount.find(queryObject);
            MongoCursor<Document> mongoCursor = findIterable.iterator();
            return mongoCursor.next();
        }catch(Exception e){
            System.err.println( e.getClass().getName() + ": " + e.getMessage() );
            return null;
        }
    }
    
    public  ArrayList<Document> listByName(BasicDBObject queryObject){
        try{
        	ArrayList<Document> result = new ArrayList<Document>();
            FindIterable<Document> findIterable = UserAccount.find(queryObject);
            MongoCursor<Document> mongoCursor = findIterable.iterator();
            while(mongoCursor.hasNext()){
            	Document document = mongoCursor.next();
            	result.add(document);
            }
            return result;
        }catch(Exception e){
            System.err.println( e.getClass().getName() + ": " + e.getMessage() );
            return null;
        }
    }
  
    public  MongoCursor<Document> listTeacherList(){
        try{
        	BasicDBObject queryObject = new BasicDBObject("type","t");
            FindIterable<Document> findIterable = UserAccount.find(queryObject);
            MongoCursor<Document> mongoCursor = findIterable.iterator();
            return mongoCursor;
        }catch(Exception e){
            System.err.println( e.getClass().getName() + ": " + e.getMessage() );
            return null;
        }
    }
}
